<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>函数的剩余参数</title>
  <!-- 
  在JavaScript中，剩余参数（Rest Parameters）是一种用于处理不定数量参数的语法。它允许我们将函数的多个参数收集到一个数组中，从而方便地处理这些参数。
  一、定义
  - 剩余参数语法：通过在参数前加上三个点（ `...` ）来定义剩余参数。该参数会收集所有未命名的参数，并将它们放入一个数组中。

  二、使用示例
  1. 基本用法：
  function sum(...numbers) {
        let total = 0;
        for (let num of numbers) {
            total += num;
        }
        return total;
    }

    console.log(sum(1, 2, 3, 4)); // 输出: 10
    console.log(sum(5, 10, 15));   // 输出: 30
  在这个例子中， `sum` 函数使用剩余参数 `...numbers` 来接收任意数量的参数，并计算它们的总和。

  2. 与其他参数结合使用：
    剩余参数可以与常规参数一起使用，但必须放在参数列表的最后。
  function multiply(factor, ...numbers) {
        return numbers.map(num => num * factor);
    }

    console.log(multiply(2, 1, 2, 3)); // 输出: [2, 4, 6]
  在这个例子中， `factor` 是常规参数，而 `...numbers` 是剩余参数，接收所有额外的参数。

  三、注意事项
  1. 只能有一个剩余参数：
    在函数定义中，只能有一个剩余参数，并且它必须是参数列表的最后一个参数。
    function example(a, ...rest, b) { // 错误，rest不能在b之前
        // ...
    }
  2. 不与 `arguments` 混用：
    剩余参数与 `arguments` 对象是不同的。 `arguments` 是一个类数组对象，而剩余参数是一个真正的数组。推荐使用剩余参数，因为它们更简洁且更易于使用。
  function example() {
        console.log(arguments); // 类数组对象
        console.log([...arguments]); // 转换为数组
    }

    function exampleWithRest(...args) {
        console.log(args); // 真实数组
    }
  四、总结

  - 剩余参数是一种方便的语法，允许函数接收不定数量的参数，并将它们收集到一个数组中。
  - 可以与常规参数结合使用，但必须放在参数列表的最后。
  - 剩余参数是一个真正的数组，使用起来比 `arguments` 对象更灵活和简洁。

   -->
</head>

<body>

  <script>
    // 剩余参数允许函数接收不定数量的参数，并将它们收集到一个数组中。
    function sum(...numbers) {
      return numbers.reduce((total, num) => total + num, 0);
    }
    console.log(sum(1, 2, 3, 4, 5)); // 输出: 15

    // 剩余参数可以与常规参数结合使用，但必须放在参数列表的最后。
    function multiply(factor, ...numbers) {
      return numbers.map(num => num * factor);
    }
    console.log(multiply(2, 1, 2, 3)); // 输出: [2, 4, 6]

    // 剩余参数是一个真正的数组，使用起来比 arguments 对象更灵活和简洁。
    function example(...args) {
      console.log(args); // 真实数组
      console.log(Array.isArray(args)); // true
    }

    example(1, 2, 3, 4, 5); // 输出: [1, 2, 3, 4, 5]

    // 剩余参数可以与 arguments 对象一起使用，但需要注意它们的区别。
    function exampleWithArguments(...args) {
      console.log(arguments); // 类数组对象
      console.log(Array.isArray(arguments)); // false
    }

    exampleWithArguments(1, 2, 3, 4, 5); // 输出: {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, length: 5}

    // 剩余参数可以用于解构赋值。
    function exampleWithDestructuring(...args) {
      const [first, second, ...rest] = args;
      console.log(first); // 输出: 1
      console.log(second); // 输出: 2
      console.log(rest); // 输出: [3, 4, 5]
    }

    exampleWithDestructuring(1, 2, 3, 4, 5); // 输出: 1 2 [3, 4, 5]

    // 剩余参数可以用于扩展运算符。
    const numbers = [1, 2, 3, 4, 5];
    console.log(...numbers); // 输出: 1 2 3 4 5

  </script>

</body>

</html>